Attribute VB_Name = "modArrayOwner"
'***************************************************************
' (c) Copyright 2000 Matthew J. Curland
'
' This file is from the CD-ROM accompanying the book:
' Advanced Visual Basic 6: Power Techniques for Everyday Programs
'   Author: Matthew Curland
'   Published by: Addison-Wesley, July 2000
'   ISBN: 0-201-70712-8
'   http://www.PowerVB.com
'
' You are entitled to license free distribution of any application
'   that uses this file if you own a copy of the book, or if you
'   have obtained the file from a source approved by the author. You
'   may redistribute this file only with express written permission
'   of the author.
'
' This file depends on:
'   References:
'     VBoostTypes6.olb (VBoost Object Types (6.0))
'     VBoost6.Dll (VBoost Object Implementation (6.0)) (optional)
'   Files:
'     VBoost.Bas (optional)
'   Minimal VBoost conditionals:
'     VBOOST_INTERNAL = 1 : VBOOST_CUSTOM = 1
'   Conditional Compilation Values:
'     NOVBOOST = 1 'Removes VBoost dependency
'
' This file is discussed in Chapters 2 and 8.
'***************************************************************
Option Explicit

Private Type ArrayOwnerVTables
    DestroyData(2) As Long
    IgnoreData(2) As Long
End Type
Private m_VTables As ArrayOwnerVTables
Private m_pVTableDestroy As Long
Private m_pVTableIgnore As Long
    
Public Type ArrayOwner
    pVTable As Long
    pThisObject As IUnknown
    SA As SafeArray1d
    'pSA() As SafeArray assumed
End Type

Public Sub InitArrayOwner(ArrayOwner As ArrayOwner, ByVal cbElements As Long, ByVal fFeatures As Integer, Optional ByVal fDestroyData As Boolean = False)
    If m_pVTableDestroy = 0 Then
        With m_VTables
            .DestroyData(0) = FuncAddr(AddressOf QueryInterface)
            .IgnoreData(0) = .DestroyData(0)
            .DestroyData(1) = FuncAddr(AddressOf AddRef)
            .IgnoreData(1) = .DestroyData(1)
            .DestroyData(2) = FuncAddr(AddressOf ReleaseDestroyData)
            .IgnoreData(2) = FuncAddr(AddressOf ReleaseIgnoreData)
            m_pVTableDestroy = VarPtr(.DestroyData(0))
            m_pVTableIgnore = VarPtr(.IgnoreData(0))
        End With
    End If
    With ArrayOwner.SA
        If .cDims = 0 Then
            .cDims = 1
            .fFeatures = fFeatures  'FADF_AUTO Or FADF_FIXEDSIZE
            .cElements = 1
            .cbElements = cbElements
            With ArrayOwner
                If fDestroyData Then
                    .pVTable = m_pVTableDestroy
                Else
                    .pVTable = m_pVTableIgnore
                End If
                #If NOVBOOST Then
                    CopyMemory .pThisObject, VarPtr(.pVTable), 4
                    CopyMemory ByVal (VarPtr(ArrayOwner) Xor &H80000000) + LenB(ArrayOwner) Xor &H80000000, VarPtr(.SA), 4
                #Else
                    VBoost.Assign .pThisObject, VarPtr(.pVTable)
                    VBoost.Assign ByVal VBoost.UAdd(VarPtr(ArrayOwner), LenB(ArrayOwner)), VarPtr(.SA)
                #End If
            End With
        End If
    End With
End Sub

Private Function QueryInterface(This As ArrayOwner, riid As Long, pvObj As Long) As Long
    Debug.Assert False 'QI not expected
    pvObj = 0
    QueryInterface = E_NOINTERFACE
End Function
Private Function AddRef(This As ArrayOwner) As Long
    Debug.Assert False 'No need to addref
End Function
Private Function ReleaseDestroyData(This As ArrayOwner) As Long
    With This
        If .SA.pvData Then
            On Error Resume Next
            SafeArrayDestroyData VarPtr(.SA)
            On Error GoTo 0
        End If
        'Zero the descriptor and array.
        ZeroMemory .SA, LenB(This) - 4
    End With
End Function
Private Function ReleaseIgnoreData(This As ArrayOwner) As Long
    'Zero the descriptor and array.
    ZeroMemory This.SA, LenB(This) - 4
End Function
Private Function FuncAddr(ByVal pfn As Long) As Long
    FuncAddr = pfn
End Function

